package com.swan.controllers;

import java.util.List;
import java.util.Optional;

import com.swan.beans.ClassBase;
import com.swan.beans.SeasonBean;
import com.swan.beans.SeasonClass;
import com.swan.models.ClassDao;
import com.swan.models.SeasonDao;
import com.swan.utils.CellFactory;
import com.swan.utils.ChoiceConvert;

import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.util.Callback;
import javafx.util.StringConverter;

/**
 * CourseSchedulingController
 * 
 * @author xyh
 * @param <T>
 * @date 20230426
 *
 */

public class CourseSchedulingController {
	@FXML
	private Button DelBtn;

	// add class fields
	@FXML
	private ChoiceBox<ChoiceConvert> SeasonChoiceBox;

	private ObservableList<ChoiceConvert> seasonChoiceList = FXCollections.observableArrayList();

	@FXML
	private ChoiceBox<ChoiceConvert> ClassChoiceBox;

	private ObservableList<ChoiceConvert> classChoiceList = FXCollections.observableArrayList();

	@FXML
	private TableView<SeasonClass> TableView;

	// Table view fields

	@FXML
	private TableColumn<SeasonClass, Boolean> SelectTableColumn;

	@FXML
	private TableColumn<SeasonClass, Integer> IdTableColumn;

	@FXML
	private TableColumn<SeasonClass, String> NameTableColumn;

	@FXML
	private TableColumn<SeasonClass, String> TitleTableColumn;

	private final ObservableList<SeasonClass> data = FXCollections.observableArrayList();

	private ClassDao dao = new ClassDao();

	private SeasonDao daoSeason = new SeasonDao();

	@FXML
	public void onDelete(ActionEvent event) {
		delete();
	}

	@FXML
	public void onAdd(ActionEvent event) {
		ChoiceConvert seasonChoice = SeasonChoiceBox.getValue();
		ChoiceConvert classChoice = ClassChoiceBox.getValue();

		if (seasonChoice.getName() != null && classChoice.getName() != null) {
			System.out.println(seasonChoice.getName() + "----" + seasonChoice.getValue());
			System.out.println(classChoice.getName() + "----" + classChoice.getValue());

			String seasonName = seasonChoice.getName();
			int seasonId = seasonChoice.getValue();

			String classTitle = classChoice.getName();
			int classId = classChoice.getValue();

			SeasonClass row = new SeasonClass();
			row.setName(seasonName);
			row.setTitle(classTitle);
			row.setSeasonId(seasonId);
			row.setClassId(classId);

			dao.bindSeasonClass(seasonId, classId);
			System.out.println("add season-class success!");
			data.add(row);
		}
	}

	private boolean delete() {
		int size = data.size();
		if (size <= 0) {
			return false;
		}
		for (int i = size - 1; i >= 0; i--) {
			SeasonClass row = data.get(i);
			if (row.getSelected()) {
				// confirm delete
				Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
				alert.setContentText("confirm delete season-class ?");
				Optional<ButtonType> showAndWait = alert.showAndWait();
				if (showAndWait.get() == ButtonType.OK) {
					data.remove(row);
					dao.unBindSeasonClass(row.getSeasonId(),row.getClassId());
					System.out.println("delete season-class success!");
				}
			}
		}
		return true;
	}

	@FXML
	private void initialize() {
		// table view
		// set select column ui
		SelectTableColumn
				.setCellFactory(CellFactory.tableCheckBoxColumn(new Callback<Integer, ObservableValue<Boolean>>() {
					@Override
					public ObservableValue<Boolean> call(Integer index) {
						final SeasonClass row = TableView.getItems().get(index);
						ObservableValue<Boolean> ret = new SimpleBooleanProperty(row, "selected", row.getSelected());
						ret.addListener(new ChangeListener<Boolean>() {
							@Override
							public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
									Boolean newValue) {
								row.setSelected(newValue);
							}
						});
						return ret;
					}
				}));

		// set column value

		SelectTableColumn.setCellValueFactory(new PropertyValueFactory<SeasonClass, Boolean>("selected"));
		NameTableColumn.setCellValueFactory(new PropertyValueFactory<SeasonClass, String>("name"));
		TitleTableColumn.setCellValueFactory(new PropertyValueFactory<SeasonClass, String>("title"));

		// set table view
		List<SeasonClass> list = dao.listSeasonClass();
		System.out.println("list season-class success!");
		data.addAll(list);

		TableView.setItems(data);
		TableView.setEditable(true);

		// init choice box
		// init class choice
		List<ClassBase> classList = dao.list();
		for (ClassBase cb : classList) {
			ChoiceConvert ccc = new ChoiceConvert(cb.getTitle(), cb.getId());
			classChoiceList.add(ccc);
		}
		ClassChoiceBox.setItems(classChoiceList);
		ClassChoiceBox.setConverter(new StringConverter<ChoiceConvert>() {
			@Override
			public String toString(ChoiceConvert object) {
				return object.getName();
			}

			@Override
			public ChoiceConvert fromString(String string) {
				System.out.println(string);
				return null;
			}
		});

		ClassChoiceBox.setSelectionModel(new SingleSelectionModel<ChoiceConvert>() {
			@Override
			protected ChoiceConvert getModelItem(int index) {
				System.out.println(index);
				ChoiceConvert choiceConvert = classChoiceList.get(index);
				return choiceConvert;
			}

			@Override
			protected int getItemCount() {
				return classChoiceList.size();
			}
		});

		// init season choice
		List<SeasonBean> seasonList = daoSeason.list();
		for (SeasonBean sb : seasonList) {
			ChoiceConvert scc = new ChoiceConvert(sb.getName(), sb.getId());
			seasonChoiceList.add(scc);
		}
		SeasonChoiceBox.setItems(seasonChoiceList);

		SeasonChoiceBox.setConverter(new StringConverter<ChoiceConvert>() {
			@Override
			public String toString(ChoiceConvert object) {
				return object.getName();
			}

			@Override
			public ChoiceConvert fromString(String string) {
				System.out.println(string);
				return null;
			}
		});

		SeasonChoiceBox.setSelectionModel(new SingleSelectionModel<ChoiceConvert>() {
			@Override
			protected ChoiceConvert getModelItem(int index) {
				System.out.println(index);
				ChoiceConvert choiceConvert = seasonChoiceList.get(index);
				return choiceConvert;
			}

			@Override
			protected int getItemCount() {
				return seasonChoiceList.size();
			}
		});
	}

}
